package cn.yotta.user.core.server.manager.captcha;

import cn.yotta.user.core.server.dto.captcha.CaptchaCheckDto;
import cn.yotta.user.core.server.dto.captcha.CaptchaDto;
import cn.yotta.user.core.server.exception.captcha.CaptchaNotMatchException;
import cn.yotta.user.core.server.iface.common.CaptchaGenerator;
import cn.yotta.user.core.server.iface.common.CaptchaStorageStrategy;
import cn.yotta.user.core.server.properties.CaptchaProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Objects;

import static cn.yotta.user.api.error.CaptchaErrorCode.CAPTCHA_NOT_MATCH;

/**
 * @author wyaoyao
 * @date 2022/11/9 16:16
 */
@Component
@Slf4j
public class CaptchaManagerImpl implements CaptchaManager {

    private final CaptchaGenerator captchaGenerator;
    private final CaptchaStorageStrategy captchaStorageStrategy;
    private final CaptchaProperties captchaProperties;

    public CaptchaManagerImpl(CaptchaGenerator captchaGenerator, CaptchaStorageStrategy captchaStorageStrategy, CaptchaProperties captchaProperties) {
        this.captchaGenerator = captchaGenerator;
        this.captchaStorageStrategy = captchaStorageStrategy;
        this.captchaProperties = captchaProperties;
    }

    @Override
    public CaptchaDto genCaptcha() {
        // 1 生成图片验证码
        final CaptchaGenerator.Captcha captcha = captchaGenerator.generateCaptcha();
        // 2 保存并生成token
        final String token = captchaStorageStrategy.save(captcha);
        return CaptchaDto.builder()
                .imageUrl(captcha.getImageUrl())
                .text(captcha.getText())
                .token(token).build();
    }

    @Override
    public void checkCaptcha(CaptchaCheckDto checkDto) {
        if (captchaProperties.getEnableMock()) {
            log.info("match captcha enable mock is true always matched");
            return;
        }
        CaptchaGenerator.Captcha captcha = captchaStorageStrategy.get(checkDto.getToken());
        // 如果缓存中是null或者说验证码不匹配
        if (Objects.isNull(captcha) ||
                !checkDto.getValue().equalsIgnoreCase(captcha.getText())) {
            throw new CaptchaNotMatchException(CAPTCHA_NOT_MATCH.getCode());
        }
    }
}
